﻿using System;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace SemanticEx.Tests
{
	[TestClass]
	public class ValidationTests
	{
		[TestMethod]
		public void Can_validate_named_groups()
		{
			var regex = new Regex(@"^(?<first>\d{1,3})\.(?<remainder>\d{1,3})\.(?<remainder>\d{1,3})\.(?<remainder>\d{1,3})$")
				.Validate("(1 <= first)&&(255 >= first)")
				.Validate("(0<=remainder) && (255>=remainder)");

			Assert.IsFalse(regex.Match("127.0.0.1234").Success);
			Assert.IsFalse(regex.Match("256.a.0.1").Success);
			Assert.IsFalse(regex.Match("127.0.0.401").Success);
			Assert.IsTrue(regex.Match("127.0.0.1").Success);
			Assert.IsTrue(regex.Match("192.168.1.1").Success);
		}

		[TestMethod]
		public void Can_subclass_validators()
		{
			var regex = new Regex(@"^(?<first>\d{1,3})\.(?<remainder>\d{1,3})\.(?<remainder>\d{1,3})\.(?<remainder>\d{1,3})$")
				.Validate("(1 <= first)&&(255 >= first)")
				.Validate("(0<=remainder) && (255>=remainder)");
			var homeCheck = regex.Validate("first==127");

			Assert.IsFalse(homeCheck.Match("127.0.0.1234").Success);
			Assert.IsFalse(homeCheck.Match("256.a.0.1").Success);
			Assert.IsFalse(homeCheck.Match("127.0.0.401").Success);
			Assert.IsTrue(homeCheck.Match("127.0.0.1").Success);
			Assert.IsFalse(homeCheck.Match("192.168.1.1").Success);
			Assert.IsTrue(homeCheck.Match("127.192.0.12").Success);
			Assert.IsFalse(homeCheck.Match("254.268.0.1").Success);
			Assert.IsFalse(homeCheck.Match("192.168.0.0").Success);
		}

		[TestMethod]
		public void Can_retrieve_group_values()
		{
			var regex = new Regex(@"^(?<first>\d{1,3})\.(?<remainder>\d{1,3})\.(?<remainder>\d{1,3})\.(?<remainder>\d{1,3})$")
				.Validate("(1 <= first)&&(255 >= first)")
				.Validate("(0<=remainder) && (255>=remainder)");
			var homeCheck = regex.Validate("first==127");
			var match = homeCheck.Match("192.168.2.12");
			var results = match.GetValues().Select(x => Convert.ToInt32(x));

			Assert.AreEqual(192, results.ElementAt(0));
			Assert.AreEqual(168, results.ElementAt(1));
			Assert.AreEqual(2, results.ElementAt(2));
			Assert.AreEqual(12, results.ElementAt(3));
		}

		[TestMethod]
		public void Can_use_ranges()
		{
			var regex = new Regex(@"^(?<first>\d{1,3})\.(?<remainder>\d{1,3})\.(?<remainder>\d{1,3})\.(?<remainder>\d{1,3})$")
				.IsInRange("first", 0x00, 0xFF)
				.IsInRange("remainder", 0x00, 0xFF);

			Assert.IsFalse(regex.Match("127.0.0.1234").Success);
			Assert.IsFalse(regex.Match("256.a.0.1").Success);
			Assert.IsFalse(regex.Match("127.0.0.401").Success);
			Assert.IsTrue(regex.Match("127.0.0.1").Success);
			Assert.IsTrue(regex.Match("192.168.1.1").Success);
		}
	}
}